{{ define "index" }}
<!doctype html>
<html>
  <head>
    <title>ShowMe-{{ .host }}</title>
    <style>body, #terminal {position: absolute; height: 100%; width: 100%; margin: 0px;}</style>
    <link rel="stylesheet" href="{{ .StaticPath }}/xterm.css" />
    <link rel="stylesheet" href="{{ .StaticPath }}/fullscreen.css" />
    <link rel="icon" href="{{ .StaticPath }}/favicon.ico" type="image/x-icon" />
    <script src="{{ .StaticPath }}/xterm.js"></script>
    <script src="{{ .StaticPath }}/fit.js"></script>
    <script src="{{ .StaticPath }}/webLinks.js"></script>
    <script src="{{ .StaticPath }}/search.js"></script>
    <script src="{{ .StaticPath }}/fullscreen.js"></script>
    <script src="{{ .StaticPath }}/base64.min.js"></script>
    <script src="{{ .StaticPath }}/reconnecting-websocket.min.js"></script>
  </head>
  <body>
    <div id="terminal" style="display: block; margin-bottom: 0px;"></div>
    <script>
      const defaultTheme = {
        lineHeight: 20,
        foreground: '#ffffff', // 字体
        background: '#000000', // 背景色 1b212f
        cursor: '#ffffff', // 设置光标
        selection: 'rgba(255, 255, 255, 0.3)',
        black: '#000000',
        brightBlack: '#808080',
        red: '#ce2f2b',
        brightRed: '#f44a47',
        green: '#00b976',
        brightGreen: '#05d289',
        yellow: '#e0d500',
        brightYellow: '#f4f628',
        magenta: '#bd37bc',
        brightMagenta: '#d86cd8',
        blue: '#1d6fca',
        brightBlue: '#358bed',
        cyan: '#00a8cf',
        brightCyan: '#19b8dd',
        white: '#e5e5e5',
        brightWhite: '#ffffff'
      }

      const bindTerminalResize = (term, websocket) => {
        const onTermResize = size => {
          // websocket.send(
          //   JSON.stringify({
          //     type: 'resize',
          //     rows: size.rows,
          //     cols: size.cols
          //   })
          // )
          console.log('resize',size)
          websocket.send('2{{ .Xsrf }}' + Base64.encode(size.rows + ':' + size.cols))
        }
        // register resize event.
        term.on('resize', onTermResize)
        // unregister resize event when WebSocket closed.
        websocket.addEventListener('close', function() {
          {{if .Reconnect}}
          console.log("close ws envent, reconnect")
          {{- else}}
          term.off('resize', onTermResize)
          {{- end}}
        })
        
      }

      const bindTerminal = (term, websocket, bidirectional, bufferedTime) => {
        term.socket = websocket
        let messageBuffer = null
        const handleWebSocketMessage = function(ev) {
          if (bufferedTime && bufferedTime > 0) {
            if (messageBuffer) {
              messageBuffer += ev.data
            } else {
              messageBuffer = ev.data
              setTimeout(function() {
                term.write(messageBuffer)
              }, bufferedTime)
            }
          } else {
            term.write(Base64.decode(ev.data))
            // term.writeUtf8(Base64.decode(ev.data))
          }
          // var myEvent = new Event('resize');
          // window.dispatchEvent(myEvent);
        }

        const handleTerminalData = function(data) {
          // websocket.send(
          //   JSON.stringify({
          //     type: 'cmd',
          //     cmd: Base64.encode(data) // encode data as base64 format
          //   })
          // )
          websocket.send('0{{ .Xsrf }}' + Base64.encode(data))

          {{if .DEBUG}}
            console.log('0{{ .Xsrf }}' + Base64.encode(data))
          {{- end}}
          // term.write(data)
        }

        websocket.onmessage = handleWebSocketMessage
        if (bidirectional) {
          term.on('data', handleTerminalData)
        }

        // send heartbeat package to avoid closing webSocket connection in some proxy environmental such as nginx.
        const heartBeatTimer = setInterval(function() {
          // websocket.send(JSON.stringify({ type: 'heartbeat', data: '' }))
          // heartbeat
          // console.log('heartbeat')
          websocket.send('3{{ .Xsrf }}' + Base64.encode('heartbeat'))
        }, 20 * 1000)

        websocket.addEventListener('close', function() {
          websocket.removeEventListener('message', handleWebSocketMessage)
          {{if .Reconnect}}
          console.log("close ws message, reconnect")
          {{- else}}
          term.off('data', handleTerminalData)
          delete term.socket
          clearInterval(heartBeatTimer)
          {{- end}}
          
        })
      }

      function doLink(ev, url) {
        if (ev.type === 'click') {
          window.open(url)
        }
      }

      Terminal.applyAddon(fit)
      Terminal.applyAddon(webLinks)
      Terminal.applyAddon(search)
      var term = new Terminal({
        rendererType: "canvas",
        rows: 35,
        cols: 100,
        convertEol: true, // 启用时，光标将设置为下一行的开头
        // scrollback: 100, // 终端中的回滚量
        disableStdin: false, // 是否应禁用输入
        cursorBlink: true, // 光标闪烁
        cursorStyle: 'bar', // 光标样式 underline
        bellStyle: 'sound',
        theme: defaultTheme
      });

      function Resize() {
        term.fit()
      }

      term._initialized = true

      term.prompt = () => {
        term.write('\r\n')
      }
      
      term.writeln('Welcome to \x1B[1;3;31mShowMe TTY\x1B[0m')
      {{if .Reconnect}}
      term.writeln('连接模式: \x1B[1;3;32mReconnect\x1B[0m')
      {{- else}}
      term.writeln('连接模式: \x1B[1;3;32mOnce\x1B[0m')
      {{- end}}

      {{if .Write}}
      term.writeln('输入模式：\x1B[1;3;31m读/写\x1B[0m')
      {{- else}}
      term.writeln('输入模式：\x1B[1;3;31m读\x1B[0m')
      {{- end}}
      
      {{if .MaxC}}
      term.writeln('连接状态：\x1B[1;3;34m{{.Conn}}/{{.MaxC}}\x1B[0m')
      {{- else}}
      term.writeln('连接总数：\x1B[1;3;34m{{.Conn}}\x1B[0m')
      {{- end}}

      term.writeln('启动参数: \x1B[1;3;30m{{ .Cmd }}\x1B[0m')
      {{if .isAduit}}
      term.writeln('后台管理: \x1B[1;3;30m{{ .Httproto}}://' + window.location.host + '{{ .Admin }}\x1B[0m')
      {{- end}}
      // term.writeln('XsrfToken: {{ .Xsrf }}')
      term.prompt()

      {{if .Debug}}
      term.on('key', function(key,ev) {
        console.log(key, ev, ev.keyCode)
      })
      {{- end}}

      // term.onData(key => {  // 粘贴的情况
      //   if(key.length > 1) term.write(key)
      // })

      // 添加事件监听器，支持输入方法
      // https://www.cnblogs.com/goloving/p/15021509.html
      // term.onKey(e => {
      //   const printable = !e.domEvent.altKey && !e.domEvent.altGraphKey && !e.domEvent.ctrlKey && !e.domEvent.metaKey
      //   if (e.domEvent.keyCode === 13) {
      //     term.prompt()
      //   } else if (e.domEvent.keyCode === 8) { // back 删除的情况
      //     if (term._core.buffer.x > 2) {
      //       term.write('\b \b')
      //     }
      //   } else if (printable) {
      //     term.write(e.key)
      //   }
      //   console.log(1,'print', e.key)
      // })

      term.open(document.getElementById('terminal'))
      window.addEventListener('resize', Resize)
      term.webLinksInit(doLink)
      term.fit()

      {{if .Reconnect}}
        console.log("Recoonect Mode")
        ws = new ReconnectingWebSocket('{{.Protocol}}://' + window.location.host + {{ .WsPath }})
      {{- else}}
        console.log("Once Mode")
        ws = new WebSocket('{{.Protocol}}://' + window.location.host + {{ .WsPath }})
      {{- end}}
      
      ws.onopen = () => {
        let rows = document.body.clientHeight / 17.3
        let cols = document.body.clientWidth / 9.02
        console.log(rows,cols)
        ws.send('2{{ .Xsrf }}' + Base64.encode(parseInt(rows) + ':' + parseInt(cols)))
        term.fit() 
      }

      ws.onerror = (e) => {
        console.error(e)
      }

      ws.onclose = () => {
        term.setOption('cursorBlink', false)
        console.log('console.web_socket_disconnect')
      }

      bindTerminal(term, ws, true, -1)
      bindTerminalResize(term, ws);
    </script>
  </body>
</html>
{{ end }}